home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d1 / freemacs.arc / MEMORY.ASM < prev    next >
Assembly Source File  |  1988-03-17  |  13KB  |  727 lines

  1. sequential_read    equ    0
  2. debugging    equ    0
  3.  
  4.     .xlist
  5.  
  6. HT    equ    09h
  7. LF    equ    0ah
  8. CR    equ    0dh
  9. LINENEW    equ    CR+LF*256    ;the way a newline is stored in memory.
  10.  
  11. bufseg    segment    public
  12.  
  13.     public    toptop,topbot,bottop,botbot,margin
  14. margin        equ    0
  15. toptop        dw    ?
  16. topbot        dw    ?
  17. bottop        dw    ?
  18. botbot        dw    ?
  19.  
  20.     extrn    memsize: word
  21.  
  22.     public    linecount, linesbefore
  23. linecount    dw    ?
  24. linesbefore    dw    ?
  25.  
  26.     public    buffer_modified
  27. buffer_modified    db    ?
  28.  
  29.     extrn    bufseg_size: byte
  30.  
  31. bufseg    ends
  32.  
  33. data    segment    byte public
  34.  
  35. ;the following externs are in 'buffers'
  36.     extrn    textseg: word
  37.  
  38. insert_ds    dw    ?
  39.  
  40.   if sequential_read
  41. read_pointer    dw    ?
  42.   endif
  43.  
  44. data    ends
  45.  
  46. b_struc    struc
  47. b    db    ?
  48. b_struc    ends
  49.  
  50. w_struc    struc
  51. w    dw    ?
  52. w_struc    ends
  53.  
  54. byte_ptr    label    byte
  55.  
  56. code    segment    byte public
  57. ;all the routines in this segment are entered with ds=data, es=data
  58.     assume    cs:code, ds:data, es:data
  59.  
  60. ;the following externs are in 'buffers'
  61.     extrn    init_all_buffers: near
  62.  
  63. ;the following externs are in 'marks'
  64.     extrn    init_marks: near
  65.     extrn    get_mark: near
  66.     extrn    adjust_marks_del: near
  67.     extrn    adjust_marks_ins: near
  68.  
  69. ;the following externs are in 'redisp'
  70.     extrn    prevline: near
  71.     extrn    nextline: near
  72.     extrn    compute_one: near
  73.  
  74.     public    init_memory
  75. init_memory:
  76. ;enter with ax=>first paragraph of available memory, bx=> first paragraph of
  77. ;  unavailable memory.
  78. ;exit with cy if no memory available.
  79.     call    init_all_buffers
  80.     jc    init_memory_1        ;if error, don't bother continuing.
  81.     clc
  82. init_memory_1:
  83.     ret
  84.  
  85.  
  86.     public    count_lines
  87. count_lines:
  88.     push    ds
  89.     mov    ds,textseg
  90.     call    count_lines$
  91.     pop    ds
  92.     ret
  93.  
  94.     public    del_to_mark
  95. del_to_mark:
  96.     push    ds
  97.     mov    ds,textseg
  98.     call    del_to_mark$
  99.     pop    ds
  100.     ret
  101.  
  102.  
  103.     public    read_mark
  104. read_mark:
  105.     mov    ds,textseg
  106.     call    read_mark$
  107.     ret
  108.  
  109.  
  110.     public    goto_mark
  111. goto_mark:
  112.     push    ds
  113.     mov    ds,textseg
  114.     call    goto_mark$
  115.     pop    ds
  116.     ret
  117.  
  118.  
  119.     public    insert_string
  120. insert_string:
  121.     push    ds
  122.     mov    ax,es            ;use data for insert_ds.
  123.     mov    ds,textseg
  124.     call    insert_string$
  125.     pop    ds
  126.     ret
  127.  
  128.  
  129.     public    set_column
  130. set_column:
  131.     push    ds
  132.     mov    ds,textseg
  133.     call    set_column$
  134.     pop    ds
  135.     ret
  136.  
  137.  
  138.     public    set_line
  139. set_line:
  140.     push    ds
  141.     mov    ds,textseg
  142.     call    set_line$
  143.     pop    ds
  144.     ret
  145.  
  146.  
  147.     public    compute_cursor
  148. compute_cursor:
  149. ;exit with dx=column.
  150.     push    ds
  151.     mov    ds,textseg
  152.     call    compute_cursor$
  153.     pop    ds
  154.     ret
  155.  
  156.  
  157.     public    store_buffer_modified
  158. store_buffer_modified:
  159.     push    ds
  160.     mov    ds,textseg
  161.     assume    ds:bufseg
  162.     mov    buffer_modified,al
  163.     pop    ds
  164.     assume    ds:data
  165.     ret
  166.  
  167.  
  168.     public    read_linecount
  169. read_linecount:
  170.     mov    bx,offset linecount
  171.     jmp    short read_variable
  172.     public    read_linesbefore
  173. read_linesbefore:
  174.     mov    bx,offset linesbefore
  175.     jmp    short read_variable
  176.     public    read_buffer_modified
  177. read_buffer_modified:
  178.     mov    bx,offset buffer_modified
  179. read_variable:
  180.     push    ds
  181.     mov    ds,textseg
  182.     assume    ds:bufseg
  183.     mov    ax,bufseg:[bx]
  184.     pop    ds
  185.     assume    ds:data
  186.     ret
  187.  
  188.  
  189.     public    file_size
  190. file_size:
  191. ;exit with ax=size of the current buffer in bytes.
  192.     mov    ds,textseg
  193.     assume    ds:bufseg
  194.     mov    ax,topbot
  195.     sub    ax,toptop
  196.     add    ax,botbot
  197.     sub    ax,bottop
  198.     push    es
  199.     pop    ds
  200.     assume    ds:data
  201.     ret
  202.  
  203.  
  204.     public    percent_full
  205. percent_full:
  206. ;return the percent full amount in ax.
  207. ;destroy ax,cx,dx.
  208.     push    ds
  209.     mov    ds,textseg
  210.     assume    ds:bufseg
  211.     mov    ax,100
  212.     mov    cx,memsize
  213.     jcxz    percent_full_1
  214.     mov    ax,botbot        ;compute the size of the buffer
  215.     sub    ax,bottop
  216.     add    ax,topbot
  217.     sub    ax,toptop
  218.     mov    dx,0
  219.     div    cx
  220.     cmp    dx,0
  221.     je    percent_full_1
  222.     inc    ax
  223. percent_full_1:
  224.     pop    ds
  225.     assume    ds:data
  226.     ret
  227.  
  228.  
  229.   if sequential_read
  230.     public    reset_to_top
  231. reset_to_top:
  232.     push    es
  233.     mov    es,textseg
  234.     assume    es:bufseg
  235.     mov    ax,toptop
  236.     mov    read_pointer,ax
  237.     pop    es
  238.     assume    es:data
  239.     ret
  240.  
  241.  
  242.     public    read_next
  243. read_next:
  244.     mov    bx,read_pointer
  245.     push    es
  246.     mov    es,textseg
  247.     assume    es:bufseg
  248.     cmp    bx,topbot        ;time to switch to bottom?
  249.     jb    read_next_1        ;no.
  250.     mov    bx,bottop
  251. read_next_1:
  252.     cmp    bx,botbot        ;end of file?
  253.     jb    read_next_2        ;no.
  254.     stc
  255.     jmp    short read_next_3
  256. read_next_2:
  257.     mov    al,[bx]
  258.     inc    bx
  259.     mov    read_pointer,bx
  260.     clc
  261. read_next_3:
  262.     pop    es
  263.     assume    es:data
  264.     ret
  265.  
  266.  
  267.     public    goto_read
  268. goto_read:
  269. ;remember not to go to the LF part of a newline!
  270.     ret                ;for now, do nothing.
  271.   endif
  272.  
  273. if debugging
  274.     extrn    chrout: near
  275.     extrn    get_next_buffer: near
  276.  
  277.     public    dump_bufseg
  278. dump_bufseg:
  279.     mov    ds,textseg
  280.     assume    ds:bufseg
  281.  
  282.     push    linesbefore
  283.     push    linecount
  284.     push    botbot
  285.     push    bottop
  286.     push    topbot
  287.     push    toptop
  288.  
  289.     mov    ax,es
  290.     mov    ds,ax
  291.     assume    ds:data
  292.  
  293.     mov    ax,textseg
  294.     call    hexout
  295.     pop    ax            ;toptop
  296.     call    hexout
  297.     pop    ax            ;topbot
  298.     call    hexout
  299.     pop    ax            ;bottop
  300.     call    hexout
  301.     pop    ax            ;botbot
  302.     call    hexout
  303.     pop    ax            ;linecount
  304.     call    hexout
  305.     pop    ax            ;linesbefore
  306.     call    hexout
  307.     call    get_next_buffer
  308. ;    call    hexout
  309. ;    ret
  310. ;fall through
  311. hexout:
  312.     push    ax
  313.     mov    ax,' '            ;print a leading space.
  314.     call    chrout
  315.     pop    ax
  316.     push    ax
  317.     mov    al,ah
  318.     call    byteout
  319.     pop    ax
  320. byteout:
  321.     push    ax
  322.     shr    al,1
  323.     shr    al,1
  324.     shr    al,1
  325.     shr    al,1
  326.     call    nibout
  327.     pop    ax
  328. nibout:
  329.     and    al,0fh
  330.     add    al,90h
  331.     daa
  332.     adc    al,40h
  333.     daa
  334.     mov    ah,0
  335.     jmp    chrout
  336.   endif
  337.  
  338. code    ends
  339.  
  340. code    segment    byte public
  341. ;all the code in this segment is entered with ds=bufseg, es=data
  342.     assume    cs:code, ds:bufseg, es:data
  343.  
  344. ;the following externs are in 'redisp'
  345.     extrn    paint_window: near
  346.     extrn    trash_line: near
  347.     extrn    window_insert: near
  348.     extrn    window_delete: near
  349.     extrn    up_lines: near
  350.     extrn    down_lines: near
  351.  
  352.     public    init_vars$
  353. init_vars$:
  354.     mov    bx,offset bufseg_size+2
  355.     mov    [bx-02].w,LINENEW
  356.     mov    toptop,bx
  357.     mov    topbot,bx
  358.     mov    bottop,bx
  359.     mov    botbot,bx
  360.     mov    [bx].w,LINENEW
  361.     mov    linecount,0
  362.     mov    linesbefore,0
  363.     mov    buffer_modified,0
  364.     ret
  365.  
  366.  
  367.     public    insert_string$
  368. insert_string$:
  369. ;enter with si,cx describing the string to insert, ax=segment of string.
  370. ;exit with cy if there isn't enough room to insert the entire string.
  371.     mov    insert_ds,ax
  372.     jcxz    insert_string_1
  373.     mov    ax,bottop        ;compute the free space.
  374.     sub    ax,topbot
  375.     cmp    ax,cx            ;is there enough room for this string?
  376.     jb    insert_string_4        ;no - give error.
  377.     mov    buffer_modified,1
  378. insert_string_2:
  379.     push    ds
  380.     mov    ds,insert_ds
  381.     mov    ax,ds:[si]        ;get an entire word, even though we might use only the low byte.
  382.     pop    ds
  383.     cmp    ax,LINENEW    ;newline?
  384.     jne    insert_string_3        ;no.
  385.     cmp    cx,2            ;must be at least two chars left.
  386.     jb    insert_string_3        ;no - can't be newline.
  387.     push    cx
  388.     push    si
  389.     call    inscrlf
  390.     pop    si
  391.     pop    cx
  392.     add    si,2
  393.     dec    cx
  394.     loop    insert_string_2
  395.     jmp    short insert_string_1
  396. insert_string_3:
  397.     push    cx
  398.     push    si
  399.     call    insone
  400.     pop    si
  401.     pop    cx
  402.     inc    si
  403.     loop    insert_string_2
  404. insert_string_1:
  405.     clc
  406.     ret
  407. insert_string_4:
  408.     stc
  409.     ret
  410.  
  411.  
  412. insone:
  413.     cmp    al,CR
  414.     jne    insone_1
  415.     mov    bx,bottop
  416.     cmp    [bx].b,LF
  417.     jne    inschar
  418.     inc    bottop
  419.     jmp    short insone_2
  420. insone_1:
  421.     cmp    al,LF
  422.     jne    inschar
  423.     mov    bx,topbot
  424.     cmp    [bx-01].b,CR
  425.     jne    inschar
  426.     dec    topbot
  427. insone_2:
  428.     mov    ax,1
  429.     call    adjust_marks_del
  430.     call    inscrlf
  431.     ret
  432.  
  433. inschar:
  434. ;insert the character in al at the point.
  435. ;unless there is no room.
  436.     mov    bx,topbot
  437.     cmp    bx,bottop
  438.     jae    inschar_1
  439.     push    ax
  440.     mov    ax,1
  441.     call    adjust_marks_ins
  442.     pop    ax
  443.     mov    di,topbot
  444.     mov    [di],al
  445.     inc    di
  446.     mov    topbot,di
  447.     call    trash_line
  448. inschar_1:
  449.     ret
  450.  
  451.  
  452. inscrlf:
  453.     mov    bx,topbot
  454.     inc    bx
  455.     cmp    bx,bottop
  456.     jae    inscrlf_3
  457.  
  458.     mov    ax,2
  459.     call    adjust_marks_ins
  460.  
  461.     mov    di,topbot
  462.     mov    [di].w,LINENEW
  463.     add    di,2
  464.     mov    topbot,di
  465.  
  466.     inc    linesbefore
  467.     inc    linecount
  468.  
  469.     call    window_insert        ;say that we inserted a line here.
  470.  
  471. inscrlf_3:
  472.     ret
  473.  
  474.  
  475. del_to_mark$:
  476.     call    get_mark
  477.     jcxz    del_to_mark_4_j_1
  478.     mov    buffer_modified,1
  479.     jc    del_to_mark_2        ;go if point>mark
  480.     push    bottop
  481.     call    move_point_backward    ;swap point and mark (sort of).
  482.     pop    si            ;pushed as bottop.
  483. del_to_mark_2:
  484.     mov    di,toptop        ;are we at the beginning of the file?
  485.     cmp    di,topbot
  486.     jne    del_to_mark_1        ;no
  487.     cmp    si,botbot        ;deleting to the end of the file?
  488.     jne    del_to_mark_1        ;no
  489.     mov    ax,si
  490.     sub    ax,bottop        ;compute the number of chars deleted.
  491.     mov    bottop,si        ;no characters left.
  492.     call    adjust_marks_del
  493.     mov    linecount,0        ;no lines left.
  494.     call    paint_window        ;trash the window.
  495. del_to_mark_4_j_1:
  496.     jmp    short del_to_mark_4    ;now exit.
  497. del_to_mark_1:
  498.     mov    bp,si            ;save the char that we delete to.
  499.     mov    ax,si            ;compute the number of chars.
  500.     sub    ax,bottop
  501.     call    adjust_marks_del    ;fix up the marks first.
  502.     mov    si,bottop        ;get the -> first char to delete.
  503. del_to_mark_3:
  504.     cmp    [si].w,LINENEW        ;a newline?
  505.     jne    del1_1            ;no - just skip this char.
  506.     inc    si            ;extra inc to skip past the CR.
  507.     dec    linecount        ;one less line.
  508.     call    window_delete        ;fix up the window.
  509. del1_1:
  510.     inc    si
  511.     cmp    bp,si
  512.     jne    del_to_mark_3
  513.     mov    bottop,si
  514.     call    trash_line
  515. ;now check for a newly created newline.
  516.     mov    bx,topbot
  517.     cmp    [bx-1].b,CR
  518.     jne    del_to_mark_4
  519.     mov    bx,bottop
  520.     cmp    [bx].b,LF
  521.     jne    del_to_mark_4
  522. ;get rid of the LF and CR seperately so that any mark that points to either
  523. ;  one will point to the newline.
  524.     inc    bottop            ;get rid of the LF
  525.     mov    ax,1
  526.     call    adjust_marks_del
  527.     dec    topbot            ;get rid of the CR
  528.     mov    ax,1
  529.     call    adjust_marks_del
  530.     call    inscrlf            ;now insert a newline.
  531. del_to_mark_4:
  532.     ret
  533.  
  534.  
  535.     public    goto_mark$
  536. goto_mark$:
  537.     call    get_mark
  538.     jcxz    goto_mark_1
  539.     jnc    goto_mark_2
  540.     call    move_point_forward
  541.     jmp    short goto_mark_1
  542. goto_mark_2:
  543.     call    move_point_backward
  544. goto_mark_1:
  545.     ret
  546.  
  547.  
  548.     public    read_mark$
  549. read_mark$:
  550.     call    get_mark
  551.     jnc    read_mark_1
  552.     mov    si,bottop
  553. read_mark_1:
  554.     ret
  555.  
  556.  
  557. move_point_backward:
  558.     mov    si,topbot
  559.     mov    di,bottop
  560.     push    es
  561.     push    ds
  562.     pop    es
  563.     std
  564.     dec    si
  565.     dec    di
  566.     push    cx
  567.     rep    movsb
  568.     pop    cx
  569.     inc    si
  570.     inc    di
  571.     cld
  572.     pop    es
  573.     mov    topbot,si
  574.     mov    bottop,di
  575.     call    count_lines$
  576.     sub    linesbefore,bx
  577.     call    up_lines
  578.     ret
  579.  
  580.  
  581. move_point_forward:
  582.     mov    si,bottop
  583.     mov    di,topbot
  584.     push    di
  585.     push    cx
  586.     push    es
  587.     push    ds
  588.     pop    es
  589.     rep    movsb
  590.     pop    es
  591.     mov    bottop,si
  592.     mov    topbot,di
  593.     pop    cx
  594.     pop    di
  595.     call    count_lines$
  596.     add    linesbefore,bx
  597.     call    down_lines
  598.     ret
  599.  
  600.  
  601. count_lines$:
  602. ;count the number of newlines contained in the text described by ds:di,cx.
  603.     push    es
  604.     push    ds
  605.     pop    es
  606.     mov    bx,0
  607. count_lines_1:
  608.     mov    al,CR
  609.     repnz    scasb
  610.     jcxz    count_lines_2
  611.     cmp    [di].b,LF
  612.     jne    count_lines_1
  613.     inc    bx
  614.     jmp    count_lines_1
  615. count_lines_2:
  616.     pop    es
  617.     ret
  618.  
  619.  
  620.     public    set_line$
  621. set_line$:
  622. ;given a line number in ax, move to that line.
  623.     dec    ax            ;linesbefore is zero based.
  624.     or    ax,ax            ;if negative, use zero.
  625.     jns    set_line_0
  626.     xor    ax,ax
  627. set_line_0:
  628.     sub    ax,linesbefore
  629.     je    set_line_1        ;go if we're already on that line.
  630.     jb    set_line_2        ;go if we're after that line.
  631.     mov    cx,ax
  632.     mov    si,bottop
  633. set_line_4:
  634.     call    nextline
  635.     loopne    set_line_4
  636.     mov    cx,si            ;compute the number of characters.
  637.     sub    cx,bottop
  638.     call    move_point_forward
  639.     jmp    short set_line_1
  640. set_line_2:
  641.     neg    ax            ;ax is the number of lines to move.
  642.     mov    cx,ax
  643.     mov    si,topbot
  644.     cmp    [si-2].w,LINENEW    ;are we at the beginning of a line?
  645.     je    set_line_3        ;yes.
  646.     call    prevline        ;no, go to the beginning of the line.
  647. set_line_3:
  648.     call    prevline
  649.     loopne    set_line_3
  650.     mov    cx,topbot        ;compute the number of characters.
  651.     sub    cx,si
  652.     call    move_point_backward
  653. set_line_1:
  654.     ret
  655.  
  656.  
  657. set_column$:
  658. ;given a column number in ax, move to that column.
  659.     mov    bx,ax        ;save the column number in bx.
  660.     dec    bx        ;columns are zero based.
  661.     mov    si,topbot
  662.     jmp    short set_column$_2
  663. set_column$_1:
  664.     dec    si
  665. set_column$_2:
  666.     cmp    [si-2].w,LINENEW
  667.     jne    set_column$_1
  668. ;now move over to the point, counting the size of characters on the way.
  669.     mov    dx,0
  670.     mov    cx,topbot
  671.     sub    cx,si
  672.     jcxz    set_column$_3
  673. set_column$_4:
  674.     cmp    dx,bx        ;are we at or past the desired column?
  675.     jae    set_column$_6    ;yes - move the point backward.
  676.     lodsb
  677.     call    compute_one
  678.     loop    set_column$_4
  679. set_column$_3:
  680. ;the desired column is somewhere after the point.
  681.     mov    si,bottop
  682. set_column$_7:
  683.     cmp    dx,bx        ;are we at or past the desired column?
  684.     jae    set_column$_5    ;yes - go to the column.
  685.     cmp    [si].w,LINENEW    ;are we at the end of the line?
  686.     je    set_column$_5    ;yes - this is as close as we can get.
  687.     lodsb            ;compute the next character.
  688.     call    compute_one
  689.     jmp    set_column$_7
  690. set_column$_5:
  691.     mov    cx,si
  692.     sub    cx,bottop
  693.     call    move_point_forward
  694.     ret
  695. set_column$_6:
  696.     call    move_point_backward
  697.     ret
  698.  
  699.  
  700.     public    compute_cursor$
  701. compute_cursor$:
  702. ;return the column in dx.
  703. ;find the beginning of this line.
  704.     mov    si,topbot
  705.     jmp    short compute_cursor$_2
  706. compute_cursor$_1:
  707.     dec    si
  708. compute_cursor$_2:
  709.     cmp    [si-2].w,LINENEW
  710.     jne    compute_cursor$_1
  711. ;now move over to the point, counting the size of characters on the way.
  712.     mov    dx,0
  713.     mov    cx,topbot
  714.     sub    cx,si
  715.     jcxz    compute_cursor$_3
  716. compute_cursor$_4:
  717.     lodsb
  718.     call    compute_one
  719.     loop    compute_cursor$_4
  720. compute_cursor$_3:
  721.     ret
  722.  
  723.  
  724. code    ends
  725.  
  726.     end
  727.